<?php

namespace console\models;

use common\models\Common;
use common\models\Status;
use yii\base\Exception;
use yii\helpers\ArrayHelper;

class RedPacket extends Common
{
    /**
     * @param float $amount 总红包金额
     * @param int $quantity 总数量
     * @param float $minRate 拨总金额的多少作为低保 数字越低 个人得到的金额差额越大
     * @param int $prizeMultiple 奖励浮动 数字越高 个人得到金额差额越大
     * @param int $precision 奖励偏移精度 10000
     * @param bool $allowBalanceLastNum 允许平衡分位分布
     * @param int $maxTimes 最多允许出现次数
     * @return array
     */
    public function buildRandomResults(
        $amount,
        $quantity,
        $minRate = 0.5,
        $prizeMultiple = 4,
        $precision = 10000
    ) {

        // 仅够低保
        if ($amount / $quantity <= 0.01) {
            $ret = [];
            for ($i = 0; $i < $quantity; $i++) {
                $ret[] = 0.01;
            }
            return $ret;
        }

        $minAmount = $this->formatMoney($amount * $minRate);

        $minMinAmount = $quantity * 0.01;
        if ($minAmount < $minMinAmount) {
            $minAmount = $minMinAmount;
        }
        $minAverage = $this->formatMoney($minAmount / $quantity);

        $ret = [];
        $last = $amount - $minAmount;
        $maxRand = $prizeMultiple * $precision;

        for ($i = 0; $i < $quantity; $i++) {
            $rate = mt_rand(0, $maxRand) / $precision;
            $changeAmount = $this->formatMoney($last / ($quantity - $i) * $rate);
            $changeAmount = $changeAmount > $last ? $last : $changeAmount;
            $thisAmount = $this->formatMoney($minAverage + $changeAmount);
            $thisAmount = number_format($thisAmount, 2);


            $ret[] = $thisAmount;
            $last -= $changeAmount;
        }
        $last = round($last, 2);
        $retCount = count($ret);
        if ($last > 0) {
            $index = $retCount - 1;
            $ret[$index] = $this->formatMoney($ret[$index] + $last);
        }


        $this->fixedResults($ret, $amount);
//
//        // 出现负数问题
//        $isHaveFushu = false;
//        foreach ($ret as $value) {
//            if ($value <= 0) {
//                $isHaveFushu = true;
//            }
//        }
//
//        if ($isHaveFushu) {
//            $ret = $this->buildRandomResults(
//                $amount,
//                $quantity,
//                0.65,
//                1,
//                10000,
//                false,
//                3
//            );
//        }

        var_dump($ret);
        var_dump(array_sum($ret));die;
        return $ret;
    }

    private function fixedResults(&$results, $amount)
    {
        $total = 0;
        foreach ($results as $r) {
            $total = bcadd($total,$r,2);
//            $total += $r;
        }
        $dis = round($amount - $total, 2);
        if ($dis >= 0.01 || $dis <= 0.01) {
//        if ($dis >= 0.01) {
            $results[count($results) - 1] = (string) bcadd($results[count($results) - 1], $dis, 2);
        }
    }

    public function getRandMoney ($maxRand = 0,$precision = 0, $index = 0, $quantity = 0, $last = 0, $minAverage = 0) {
        $rate = mt_rand(0, $maxRand) / $precision;
        $changeAmount = $this->formatMoney($last / ($quantity - $index) * $rate);
        $changeAmount = $changeAmount > $last ? $last : $changeAmount;
        $thisAmount = $this->formatMoney($minAverage + $changeAmount);
        return [$changeAmount,number_format($thisAmount, 2)];
    }

    private function formatMoney($money)
    {
        return floatval(number_format($money, 2, '.', ''));
    }




    public function generateRedPacket($total, $num, $average) {
        // 创建一个长度为num-1的结果数组
        $result = array();
        // 初始化总金额
        $sum = (float) $total;

        // 遍历每一个人
        for ($i = 0; $i < $num-1; $i++) {
            // 从总金额中随机获取一定的金额
            $amount = mt_rand() / mt_getrandmax() * ($sum * $average / $num);
            // 将金额转换为两位小数
//            $amount = (float) number_format($amount, 2);
            $amount = $this->formatMoney($amount);

            // 如果金额为0，则重新随机获取一定的金额
            while ($amount == 0) {
                echo "amount == 0";
                $amount = mt_rand() / mt_getrandmax() * ($sum * 2 / $num);
                $amount = $this->formatMoney($amount);
            }

            // 将金额存入结果数组
            $result[$i] = number_format($amount, 2, '.', '');
            // 总金额减去金额
            $sum -= $amount;
        }

        // 将总金额存入结果数组
        $result[$num-1] = number_format($sum, 2, '.', '');
        // 返回结果数组
        return $result;
    }

    public function calculateTotalAmount($redPackets) {
        // 初始化总金额
        $total = 0.0;
        // 遍历结果数组
        foreach ($redPackets as $amount) {
            // 将金额加到总金额中
            $total += $amount;
        }
        // 返回总金额
        return $total;
    }

    public function sendRedPacket() {
        // 金额
        $total = 10;
// 人数
        $num = 6;
// 红包均值1-5 数字越大越靠前
        $average = 2;

// 创建一个长度为num-1的结果数组
        $redPackets = $this->generateRedPacket($total, $num, $average);
// 遍历结果数组
        foreach ($redPackets as $i => $amount) {
            // 打印每一个人抢到的金额
            echo "第 ".($i+1)." 个人抢到的红包金额为：".$amount."\n";
        }

// 计算总金额
        $totalAmount = $this->calculateTotalAmount($redPackets);
// 打印总金额
        echo "所有人抢到的金额总和为：".$totalAmount."\n";

    }


}